package nadav.tasher.lightool.graphics.view.appview.drawer;

import nadav.tasher.lightool.info.Device;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.StackLayout;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.Point;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;

import java.util.ArrayList;

public class Drawer extends DirectionalLayout {
    private AnimatorProperty animation;
    private int animationTime = 400;
    private StackLayout drawerView;
    private Component closer;
    private ArrayList<OnState> onStates=new ArrayList<>();

    public Drawer(Context context) {
        super(context);
        init();
    }

    private void init(){
        drawerView = new StackLayout(getContext());
        drawerView.setLayoutConfig(new LayoutConfig((ComponentContainer.LayoutConfig.MATCH_PARENT),0));
        closer = new Component(getContext());
        closer.setLayoutConfig(new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,ComponentContainer.LayoutConfig.MATCH_PARENT));
        closer.setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (isOpen()) close();
            }
        });
        closer.setVisibility(INVISIBLE);
        setOrientation(DirectionalLayout.VERTICAL);
        setLayoutDirection(LayoutDirection.LTR);
        setLayoutConfig(new LayoutConfig(LayoutConfig.MATCH_PARENT,ComponentContainer.LayoutConfig.MATCH_CONTENT));
        setAlignment(LayoutAlignment.CENTER);
        setMarginLeft(15);
        setMarginRight(22);
        addComponent(drawerView);
        addComponent(closer);
    }
    public void setAnimationTime(int animationTime) {
        this.animationTime = animationTime;
    }

    public void open(double percent){
        if (!isAnimating()){
            percent=Math.abs(percent);
            closer.setVisibility(VISIBLE);
            drawerView.setLayoutConfig(new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,(int)(screenY(getContext())*percent)));
            animation=new AnimatorProperty();
            animation.setTarget(Drawer.this);
            float[] values = getAnimation(true);
            animation.moveFromY(values[0]);
            animation.moveToY(values[1]);
            animation.setDuration(animationTime);
            animation.setCurveType(AnimatorProperty.CurveType.LINEAR);
            animation.setStateChangedListener(new Animator.StateChangedListener() {
                @Override
                public void onStart(Animator animator) {
                    if (isOpen()){
                        for (int a = 0; a < onStates.size(); a++){
                            onStates.get(a).onOpen();
                        }
                        for (int a = 0; a < onStates.size(); a++) {
                            onStates.get(a).onBoth(isOpen());
                        }
                    }
                }

                @Override
                public void onStop(Animator animator) {

                }

                @Override
                public void onCancel(Animator animator) {

                }

                @Override
                public void onEnd(Animator animator) {

                }

                @Override
                public void onPause(Animator animator) {

                }

                @Override
                public void onResume(Animator animator) {

                }
            });
            animation.start();
        }
    }

    private float[] getAnimation(boolean open) {
        float[] animation;
        if (open) {
            animation = new float[]{
                    -drawerView.getLayoutConfig().height,
                    0+10
            };
        } else {
            animation = new float[]{
                    0+10,
                    -drawerView.getLayoutConfig().height
            };
        }
        return animation;
    }

    public void close(){
        if (!isAnimating()){
            closer.setVisibility(Component.INVISIBLE);
            animation=new AnimatorProperty();
            animation.setTarget(Drawer.this);
            float[] values = getAnimation(false);
            animation.moveFromY(values[0]);
            animation.moveToY(values[1]);
            animation.setDuration(animationTime);
            animation.setCurveType(AnimatorProperty.CurveType.LINEAR);
            animation.setStateChangedListener(new Animator.StateChangedListener() {
                @Override
                public void onStart(Animator animator) {

                }

                @Override
                public void onStop(Animator animator) {

                }

                @Override
                public void onCancel(Animator animator) {

                }

                @Override
                public void onEnd(Animator animator) {
                    drawerView.setLayoutConfig(new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, 0));
                    if (!isOpen()) {
                        for (int a = 0; a < onStates.size(); a++) {
                            onStates.get(a).onClose();
                        }
                        for (int a = 0; a < onStates.size(); a++) {
                            onStates.get(a).onBoth(isOpen());
                        }
                    }

                }

                @Override
                public void onPause(Animator animator) {

                }

                @Override
                public void onResume(Animator animator) {

                }
            });
            animation.start();
        }
    }


    public boolean isAnimating() {
        return animation != null && animation.isRunning();
    }

    public boolean isOpen(){
        return drawerView.getLayoutConfig() != null && drawerView.getLayoutConfig().height !=0;
    }

    public  StackLayout getDrawerView(){
        return drawerView;
    }

    public Component getContent(){
        if (drawerView.getChildCount()>0){
            return drawerView.getComponentAt(0);
        }else {
            return null;
        }
    }

    public void setContent(Component v) {
        drawerView.removeAllComponents();
        drawerView.addComponent(v);
    }

    public void addOnState(OnState onState) {
        onStates.add(onState);
    }

    public void removeOnState(OnState onState) {
        onStates.remove(onState);
    }

    public void removeAllOnStates() {
        onStates.clear();
    }

    public void emptyContent() {
        drawerView.removeAllComponents();
    }

    public interface OnState {
        void onOpen();

        void onClose();

        void onBoth(boolean isOpened);
    }

    public  int screenY(Context con) {
        Point p = new Point();
        DisplayManager.getInstance().getDefaultDisplay(this.getContext()).get().getSize(p);
        return (int)p.getPointY();
    }
}
